import fg from "fast-glob";
import fs from "fs-extra";
import path from "path";
import { BaseTask, TaskResult } from "../../common/tasks/BastTask.js";
import { ignoreSVN } from "../../CommonAction.js";
import { layatoolchain } from "../../layatoolchain.js";
import { toolchain } from "../../toolchain.js";
import { md5 } from "../../tools/vendor.js";

export class LayaBuildPatchTask extends BaseTask<void> {
    async run(): Promise<TaskResult<void>> {
        // 先计算所有文件的md5
        const files = await fg('**/*', { cwd: layatoolchain.vars.publishRoot });
        for (const f of files) {
            if (!(f in layatoolchain.vars.md5Map)) {
                layatoolchain.vars.md5Map[f] = md5(await fs.readFile(path.join(layatoolchain.vars.publishRoot, f)));
            }
        }

        const pfs = this.cmdOption.gameIds.split(/,\s*/);
        // 从多个pf中提取不同cdn的进行打包
        const cdnMap: { [resurl: string]: string } = {};
        for (const pf of pfs) {
            const buildConfig = layatoolchain.vars.buildConfigMap[pf];
            const pfRoot = layatoolchain.projectFilesRoot(pf, toolchain.params.projectType);
            const patchFolder = path.join(pfRoot, 'patch');

            if (cdnMap[buildConfig.resurl]) {
                // 和其它渠道共享一个CDN
                layatoolchain.vars.patchMap[pf] = cdnMap[buildConfig.resurl];
                console.log('share patch for:', pf, cdnMap[buildConfig.resurl]);
                continue;
            }
            cdnMap[buildConfig.resurl] = patchFolder;
            layatoolchain.vars.patchMap[pf] = patchFolder;

            console.log('making patch for:', pf);

            const md5FolderPath = layatoolchain.pfPublishRecRoot(this.cmdOption.oldToolsRoot, pf);
            const md5ConfigPath = path.join(md5FolderPath, 'md5.txt');
            await toolchain.svnClient.revert(md5ConfigPath);
            await toolchain.svnClient.update(md5ConfigPath);
            const oldMd5Rec = await fs.readJSON(md5ConfigPath);

            // 忽略patch文件夹
            await ignoreSVN(toolchain.params.workSpacePath, [path.relative(toolchain.params.workSpacePath, patchFolder).replaceAll(path.sep, '/')]);
            await fs.ensureDir(patchFolder);
            await fs.emptyDir(patchFolder);
            for (const f of files) {
                if (layatoolchain.vars.md5Map[f] != oldMd5Rec[f]) {
                    const dst = path.join(patchFolder, f);
                    await fs.ensureDir(path.dirname(dst));
                    await fs.copyFile(path.join(layatoolchain.vars.publishRoot, f), dst);
                }
            }
            
            await fs.writeJson(md5ConfigPath, layatoolchain.vars.md5Map, { spaces: 2 });
        }

        return { success: true, errorCode: 0, data: void 0 };
    }
}
